
#include "../User/TASK/DataStorage.h"


//******************************struct***************************************//
ControllerID_union ControllerID;
ControllerFun_union ControllerFun;
RemoteConfig_union RemoteConfig;
DeviceInfo_struct Device;
RoomInfo_struct Room;
TASKInfo_S_struct TASKInfo_S;
TASKInfo_I_struct TASKInfo_I;

extern Buzzer_Struct Buzzer;

//******************************fuction***************************************//
void vdatastorageControllerIDInit(void);
void vdatastorageControllerFunInit(void);
void vdatastorageRemoteConfigInit(void);
void vdatastorageDeviceInit(void);
void vdatastorageRoomInit(void);
void vdatastorageTaskIInit(void);
void vdatastorageTaskSInit(void);
void vdatastorageAppBackUpInit(void);

//*********************************************************************//
bool initflag = false;
uint8_t backupdata[4096];

//*********************************************************************//
/*!
    \brief      Init data Storage  IF data value 0xFF then Restore
								data list: ID Fun Remote Device room task backup
    \param[in]  none
    \param[out] none
    \retval     none
*/
void vdatastorageInit(void)
{
    //vgd25q64EraseSector(PosGD25Q64_flechazo);
    //ID
    vgd25q64ReadData(ControllerID.Byte, PosGD25Q64_flechazo, 44);
    vdatastorageControllerIDInit();
    //vgd25q64ReadData(ControllerID.Byte,PosGD25Q64_flechazo,44);
    //Fun
    vgd25q64ReadData(ControllerFun.Byte, PosGD25Q64_FunctionalConfiguration, 4);
    vdatastorageControllerFunInit();
    //vgd25q64ReadData(ControllerFun.Byte,PosGD25Q64_FunctionalConfiguration,4);
    //Remote
    vgd25q64ReadData(RemoteConfig.Byte, PosGD25Q64_RemoteControl, 18);
    vdatastorageRemoteConfigInit();
    //vgd25q64ReadData(RemoteConfig.Byte,PosGD25Q64_RemoteControl,18);
    //num of Device
    vgd25q64ReadData(Device.num, PosGD25Q64_NumberOfDevice, 2);
    vdatastorageDeviceInit();
    //vgd25q64ReadData(Device.num,PosGD25Q64_NumberOfDevice,2);
    //Device
    vgd25q64ReadData((uint8_t *)Device.Info, PosGD25Q64_DeviceInfo, ((Device.num[0] << 8) + Device.num[1]) * 11);
    //num of room
    vgd25q64ReadData(&Room.num, PosGD25Q64_NumberOfRoom, 1);
    vdatastorageRoomInit();
    //vgd25q64ReadData(&Room.num,PosGD25Q64_NumberOfRoom,1);
    //room
    vgd25q64ReadData((uint8_t *)Room.Info, PosGD25Q64_RoomInfo, Room.num);
    //num of task_i
    vgd25q64ReadData(TASKInfo_I.num, PosGD25Q64_TaskInfo_num_I, 2);
    vdatastorageTaskIInit();
    //vgd25q64ReadData(TASKInfo_I.num,PosGD25Q64_TaskInfo_num_I,2);
    //num of task_s
    vgd25q64ReadData(TASKInfo_S.num, PosGD25Q64_TaskInfo_num_S, 2);
    vdatastorageTaskSInit();
    //vgd25q64ReadData(TASKInfo_S.num,PosGD25Q64_TaskInfo_num_S,2);
    //index of task
    vtaskIndexInit();
    //app backup
    vgd25q64ReadData(backupdata, PosGD25Q64_Bootloader_APP_Backup, 4096);
    vdatastorageAppBackUpInit();

    Buzzer.control.SetRing(2, 35);
}

/*!
    \brief      ControllerIDInit
    \param[in]  none
    \param[out] none
    \retval     none
*/
void vdatastorageControllerIDInit(void)
{
    initflag = false;
    if((ControllerID.Info.flechazo[0] == 0xFF) && (ControllerID.Info.flechazo[1] == 0xFF))
    {
        ControllerID.Info.flechazo[0] = 0xFC;
        ControllerID.Info.flechazo[1] = 0x1F;
        ControllerID.Info.flechazo[2] = 0x20;
        ControllerID.Info.flechazo[3] = 0x00;
        ControllerID.Info.flechazo[4] = 0x03;
        ControllerID.Info.flechazo[5] = 0x13;
        ControllerID.Info.flechazo[6] = 0xF1;
        ControllerID.Info.flechazo[7] = 0xCF;
        initflag = true;
    }
    if((ControllerID.Info.version[0] == 0xFF) && (ControllerID.Info.version[1] == 0xFF))
    {
        ControllerID.Info.version[0] = 0x20;
        ControllerID.Info.version[1] = 0x23;
        ControllerID.Info.version[2] = 0x04;
        ControllerID.Info.version[3] = 0x18;
        initflag = true;
    }
    if((ControllerID.Info.OwnID[0] == 0xFF) && (ControllerID.Info.OwnID[1] == 0xFF))
    {



    }
    if((ControllerID.Info.LeaderID[0] == 0xFF) && (ControllerID.Info.LeaderID[1] == 0xFF))
    {
        ControllerID.Info.LeaderID[0] = 0x00;
        ControllerID.Info.LeaderID[1] = 0x00;
        ControllerID.Info.LeaderID[2] = 0x00;
        ControllerID.Info.LeaderID[3] = 0x00;
        ControllerID.Info.LeaderID[4] = 0x00;
        ControllerID.Info.LeaderID[5] = 0x00;
        ControllerID.Info.LeaderID[6] = 0x00;
        ControllerID.Info.LeaderID[7] = 0x00;
        initflag = true;
    }
    if((ControllerID.Info.LeaderID_flechazo[0] == 0xFF) && (ControllerID.Info.LeaderID_flechazo[1] == 0xFF))
    {
        ControllerID.Info.LeaderID_flechazo[0] = 0xFC;
        ControllerID.Info.LeaderID_flechazo[1] = 0x1F;
        ControllerID.Info.LeaderID_flechazo[2] = 0x20;
        ControllerID.Info.LeaderID_flechazo[3] = 0x00;
        ControllerID.Info.LeaderID_flechazo[4] = 0x03;
        ControllerID.Info.LeaderID_flechazo[5] = 0x13;
        ControllerID.Info.LeaderID_flechazo[6] = 0xF1;
        ControllerID.Info.LeaderID_flechazo[7] = 0xCF;
        initflag = true;
    }
    if((ControllerID.Info.OwnID_flechazo[0] == 0xFF) && (ControllerID.Info.OwnID_flechazo[1] == 0xFF))
    {
        ControllerID.Info.OwnID_flechazo[0] = 0xFC;
        ControllerID.Info.OwnID_flechazo[1] = 0x1F;
        ControllerID.Info.OwnID_flechazo[2] = 0x20;
        ControllerID.Info.OwnID_flechazo[3] = 0x00;
        ControllerID.Info.OwnID_flechazo[4] = 0x03;
        ControllerID.Info.OwnID_flechazo[5] = 0x13;
        ControllerID.Info.OwnID_flechazo[6] = 0xF1;
        ControllerID.Info.OwnID_flechazo[7] = 0xCF;
        initflag = true;
    }
    if(initflag)
    {
        //vgd25q64WriteData(ControllerID.Byte,PosGD25Q64_flechazo,44);
        vgd25q64FlushWrite(ControllerID.Byte, PosGD25Q64_flechazo, 44);
    }
}

/*!
    \brief      ControllerFunInit
    \param[in]  none
    \param[out] none
    \retval     none
*/
void vdatastorageControllerFunInit(void)
{
    initflag = false;
    if((ControllerFun.Byte[0] == 0xFF) && (ControllerFun.Byte[1] == 0xFF) && (ControllerFun.Byte[2] == 0xFF) && (ControllerFun.Byte[3] == 0xFF))
    {
        ControllerFun.Info.led = 1;
        ControllerFun.Info.buzzer = 1;
        ControllerFun.Info.remote = 1;
        ControllerFun.Info.key = 0;

        ControllerFun.Info.task_i = 1;
        ControllerFun.Info.task_s = 1;
        ControllerFun.Info.route = 1;
        ControllerFun.Info.rs485 = 1;

        ControllerFun.Info.lora = 1;
        ControllerFun.Info.enthrough = 0;
        ControllerFun.Info.throughusart0 = 0;
        ControllerFun.Info.throughusart1 = 0;

        ControllerFun.Info.throughusart2 = 0;
        initflag = true;
    }
    if(initflag)
    {
        vgd25q64FlushWrite(ControllerFun.Byte, PosGD25Q64_FunctionalConfiguration, 4);
    }
}
/*!
    \brief      RemoteConfigInit
    \param[in]  none
    \param[out] none
    \retval     none
*/
void vdatastorageRemoteConfigInit(void)
{
    initflag = false;
    if((RemoteConfig.Info.TimingAuto[0] == 0xFF) && (RemoteConfig.Info.TimingAuto[1] == 0xFF))
    {
        RemoteConfig.Info.offices = 0x00;
        RemoteConfig.Info.room = 0x01;
        RemoteConfig.Info.TimingAuto[0] = 0x00;
        RemoteConfig.Info.TimingAuto[1] = 0x00;
        RemoteConfig.Info.TimingAuto[2] = 0x02;
        RemoteConfig.Info.TimingAuto[3] = 0x58;
        RemoteConfig.Info.TimingStandard[0] = 0x00;
        RemoteConfig.Info.TimingStandard[1] = 0x00;
        RemoteConfig.Info.TimingStandard[2] = 0x04;
        RemoteConfig.Info.TimingStandard[3] = 0x80;
        RemoteConfig.Info.TimingStrengthen[0] = 0x00;
        RemoteConfig.Info.TimingStrengthen[1] = 0x00;
        RemoteConfig.Info.TimingStrengthen[2] = 0x07;
        RemoteConfig.Info.TimingStrengthen[3] = 0x08;
        RemoteConfig.Info.TimingSaturation[0] = 0x00;
        RemoteConfig.Info.TimingSaturation[1] = 0x00;
        RemoteConfig.Info.TimingSaturation[2] = 0x09;
        RemoteConfig.Info.TimingSaturation[3] = 0x60;
        initflag = true;
    }
    if(initflag)
    {
        vgd25q64FlushWrite(RemoteConfig.Byte, PosGD25Q64_RemoteControl, 18);
    }
}
/*!
    \brief      DeviceInit
    \param[in]  none
    \param[out] none
    \retval     none
*/
void vdatastorageDeviceInit(void)
{
    initflag = false;
    if((Device.num[0] == 0xFF) && (Device.num[1] == 0xFF))
    {
        Device.num[0] = 0;
        Device.num[1] = 0;
        initflag = true;
    }
    if(initflag)
    {
        vgd25q64FlushWrite(Device.num, PosGD25Q64_NumberOfDevice, 2);
    }
}
/*!
    \brief      RoomInit
    \param[in]  none
    \param[out] none
    \retval     none
*/
void vdatastorageRoomInit(void)
{
    initflag = false;
    if(Room.num == 0xFF)
    {
        Room.num = 0;
        initflag = true;
    }
    if(initflag)
    {
        vgd25q64FlushWrite(&Room.num, PosGD25Q64_NumberOfRoom, 1);
    }
}
/*!
    \brief      TaskIInit
    \param[in]  none
    \param[out] none
    \retval     none
*/
void vdatastorageTaskIInit(void)
{
    initflag = false;
    if((TASKInfo_I.num[0] == 0xFF) && (TASKInfo_I.num[1] == 0xFF))
    {
        TASKInfo_I.num[0] = 0;
        TASKInfo_I.num[1] = 0;
        initflag = true;
    }
    if(initflag)
    {
        vgd25q64FlushWrite(TASKInfo_I.num, PosGD25Q64_TaskInfo_num_I, 2);
    }
}
/*!
    \brief      TaskSInit
    \param[in]  none
    \param[out] none
    \retval     none
*/
void vdatastorageTaskSInit(void)
{
    initflag = false;
    if((TASKInfo_S.num[0] == 0xFF) && (TASKInfo_S.num[1] == 0xFF))
    {
        TASKInfo_S.num[0] = 0;
        TASKInfo_S.num[1] = 0;
        initflag = true;
    }
    if(initflag)
    {
        vgd25q64FlushWrite(TASKInfo_S.num, PosGD25Q64_TaskInfo_num_S, 2);
    }
}
/*!
    \brief      AppBackUpInit
    \param[in]  none
    \param[out] none
    \retval     none
*/
void vdatastorageAppBackUpInit(void)
{
    initflag = false;
    int len = 0;
    for(int i = 0; i < 1024; i++)
    {
        if(backupdata[i] == 0xFF)
        {
            len++;
            if(len >= 64)
            {
                initflag = true;
                break;
            }
        }
        else
        {
            len = 0;
        }
    }
    if(initflag)
    {
        //backup app


    }

}
/*!
    \brief      CopyArray
    \param[in]  sourcearray
    \param[in]  targetarray
    \param[in]  length
    \param[out] none
    \retval     none
*/
void vdatastorageCopyArray(uint8_t *sourcearray, uint8_t *targetarray, uint32_t length)
{
    for(uint32_t i = 0; i < length; i++)
    {
        targetarray[i] = sourcearray[i];
    }
}
/*!
    \brief      CheckArraySame
    \param[in]  sourcearray
    \param[in]  targetarray
    \param[in]  len
    \param[out] none
    \retval     none
*/
bool vdatastorageCheckArraySame(uint8_t *sourcearray, uint8_t *targetarray, uint32_t len)
{
    for(uint32_t i = 0; i < len; i++)
    {
        if(sourcearray[i] != targetarray[i])
        {
            return false;
        }
    }
    return true;
}

/*!
    \brief      MergeArray
    \param[in]  array uint8_t
    \param[out] uint32_t
    \retval     none
*/
uint32_t vdatastorageMergeArray(uint8_t *array)
{
    return ((((((array[0] << 8) + array[1]) << 8) + array[2]) << 8) + array[3]);
}

/*!
    \brief      MergeArray
    \param[in]  array uint8_t
    \param[out] uint16_t
    \retval     none
*/
uint16_t vdatastorageMergeArrayto16(uint8_t *array)
{
    return (array[0] << 8) + array[1];
}
